package dk.liljedahl.christian.apx.shipdaemon;

import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public class ArduinoDetails extends Dialog {

	protected Object result;
	protected Shell shlArduinoValues;
	private Composite composite_analogValues;
	
	private Mediator myMediator;
	private Composite composite_digitalValues;

	/**
	 * Create the dialog.
	 * @param parent
	 * @param style
	 */
	public ArduinoDetails(Shell parent, int style, Mediator mediator) {
		super(parent, style);
		setText("SWT Dialog");
		
		myMediator = mediator;
	}

	/**
	 * Open the dialog.
	 * @return the result
	 */
	public Object open() {
		createContents();
		shlArduinoValues.open();
		shlArduinoValues.layout();
		Display display = getParent().getDisplay();
		
		// Update data
		fillArduinoValues();
		while (!shlArduinoValues.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shlArduinoValues = new Shell(getParent(), getStyle());
		shlArduinoValues.setSize(600, 303);
		shlArduinoValues.setText("Arduino values");
		shlArduinoValues.setLayout(new FormLayout());
		
		Group grpAnalogPins = new Group(shlArduinoValues, SWT.NONE);
		grpAnalogPins.setLayout(new FillLayout(SWT.HORIZONTAL));
		FormData fd_grpAnalogPins = new FormData();
		fd_grpAnalogPins.left = new FormAttachment(0, 10);
		fd_grpAnalogPins.right = new FormAttachment(100, -10);
		fd_grpAnalogPins.bottom = new FormAttachment(0, 70);
		fd_grpAnalogPins.top = new FormAttachment(0);
		grpAnalogPins.setLayoutData(fd_grpAnalogPins);
		grpAnalogPins.setText("Analog pins");
		
		Composite composite_analogPins = new Composite(grpAnalogPins, SWT.NONE);
		composite_analogPins.setLayout(new FillLayout(SWT.VERTICAL));
		
		Composite composite_analogLabels = new Composite(composite_analogPins, SWT.NONE);
		composite_analogLabels.setLayout(new FillLayout(SWT.HORIZONTAL));

		// Loop and make 6 labels in composite_analogLabels
		for(int i = 0;i<6;i++){
			Label lbl = new Label(composite_analogLabels, SWT.NONE);
			lbl.setText("Pin " + i);
			lbl.setAlignment(SWT.RIGHT);
			lbl.setFont(SWTResourceManager.getFont("Tahoma", 8, SWT.BOLD));

		}
		
		composite_analogValues = new Composite(composite_analogPins, SWT.NONE);
		composite_analogValues.setLayout(new FillLayout(SWT.HORIZONTAL));

		// Loop and make 6 labels for analog data
		for(int i = 0;i<6;i++){
			Label lbl = new Label(composite_analogValues, SWT.NONE);
			lbl.setText(""+i);
			lbl.setAlignment(SWT.RIGHT);			
		}

		
		Group grpDigitalPins = new Group(shlArduinoValues, SWT.NONE);
		grpDigitalPins.setText("Digital pins");
		grpDigitalPins.setLayout(new FillLayout(SWT.HORIZONTAL));
		FormData fd_grpDigitalPins = new FormData();
		fd_grpDigitalPins.top = new FormAttachment(grpAnalogPins, 6);
		fd_grpDigitalPins.left = new FormAttachment(grpAnalogPins, 0, SWT.LEFT);
		fd_grpDigitalPins.right = new FormAttachment(100, -10);
		grpDigitalPins.setLayoutData(fd_grpDigitalPins);
		
		Composite composite_digitalPins = new Composite(grpDigitalPins, SWT.NONE);
		composite_digitalPins.setLayout(new FillLayout(SWT.VERTICAL));
		
		Composite composite_digitalLabels = new Composite(composite_digitalPins, SWT.NONE);
		composite_digitalLabels.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		composite_digitalValues = new Composite(composite_digitalPins, SWT.NONE);
		composite_digitalValues.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		Button btnReadArduinoValues = new Button(shlArduinoValues, SWT.NONE);
		fd_grpDigitalPins.bottom = new FormAttachment(100, -127);
		btnReadArduinoValues.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				fillArduinoValues();
			}
		});
		FormData fd_btnReadArduinoValues = new FormData();
		fd_btnReadArduinoValues.top = new FormAttachment(grpDigitalPins, 6);
		fd_btnReadArduinoValues.left = new FormAttachment(grpAnalogPins, 0, SWT.LEFT);
		btnReadArduinoValues.setLayoutData(fd_btnReadArduinoValues);
		btnReadArduinoValues.setText("Read Arduino Values");
		
		Group grpPinmodes = new Group(shlArduinoValues, SWT.NONE);
		grpPinmodes.setText("Pinmodes");
		grpPinmodes.setLayout(new FillLayout(SWT.HORIZONTAL));
		FormData fd_grpPinmodes = new FormData();
		fd_grpPinmodes.right = new FormAttachment(grpAnalogPins, 0, SWT.RIGHT);
		fd_grpPinmodes.bottom = new FormAttachment(100, -3);
		fd_grpPinmodes.left = new FormAttachment(grpAnalogPins, 0, SWT.LEFT);
		grpPinmodes.setLayoutData(fd_grpPinmodes);
		
		Composite compositePinmodes = new Composite(grpPinmodes, SWT.NONE);
		compositePinmodes.setLayout(new FillLayout(SWT.VERTICAL));
		
		Composite composite_PinmodeLabels = new Composite(compositePinmodes, SWT.NONE);
		composite_PinmodeLabels.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		Label lblPin = new Label(composite_PinmodeLabels, SWT.NONE);
		lblPin.setText("Pin");
		
		Composite composite_PinmodeButtons = new Composite(compositePinmodes, SWT.NONE);
		composite_PinmodeButtons.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		Label lblState = new Label(composite_PinmodeButtons, SWT.NONE);
		lblState.setText("State");
		
		
		// Loop and make 14 labels in composite_digitalLabels
		for(int i = 0;i<14;i++){
			Label lbl = new Label(composite_digitalLabels, SWT.NONE);
			lbl.setText("d" + i);
			lbl.setAlignment(SWT.RIGHT);
			lbl.setFont(SWTResourceManager.getFont("Tahoma", 8, SWT.BOLD));
		}
		// Loop and make 14 labels for digital values
		for(int i = 0;i<14;i++){
			Label lbl = new Label(composite_digitalValues, SWT.NONE);
			lbl.setText("" + i);
			lbl.setAlignment(SWT.RIGHT);			
			//  note RX TX
			if(i == 0){
				lbl.setText("rx");
			}
			if(i == 1){
				lbl.setText("tx");
			}
		}
		
		// Pinmode labels and buttons
		// Loop and make 14 labels in composite_PinmodeLabels
		for(int i = 0;i<14;i++){
			Label lbl = new Label(composite_PinmodeLabels, SWT.NONE);
			lbl.setText("d" + i);
			lbl.setAlignment(SWT.CENTER);
			lbl.setFont(SWTResourceManager.getFont("Tahoma", 8, SWT.BOLD));
		}

		// Add to labels for RX
		for(int i = 0;i<1;i++){
			Label lbl = new Label(composite_PinmodeButtons, SWT.NONE);
			lbl.setText("RX");
			lbl.setAlignment(SWT.CENTER);
		}
		// Add to labels for TX
		for(int i = 1;i<2;i++){
			Label lbl = new Label(composite_PinmodeButtons, SWT.NONE);
			lbl.setText("TX");
			lbl.setAlignment(SWT.CENTER);
		}
		// Loop and make 14 labels in composite_PinmodeButtons		
		for(int i = 2;i<14;i++){
			final Button btn = new Button(composite_PinmodeButtons, SWT.TOGGLE);
			final int pin = i;

			// We should loop the preferences here and set the buttons accordingly
			String savedPinmode = myMediator.prefs.get("pinmode"+pin, "IN");
			if(savedPinmode.equals("IN")){
				// Set the buttontext
				btn.setText("IN");
				// Set the button look
				btn.setSelection(true);
				// We do not set the actual pinmode, since this should be set automaticall after connection to the arduino
				
			}
			if(savedPinmode.equals("OUT")){
				// Set the buttontext
				btn.setText("OUT");
				// Set the button look
				btn.setSelection(false);
				// We do not set the actual pinmode, since this should be set automaticall after connection to the arduino
			}
			
			btn.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					// Figure out the new state
					boolean btnState = btn.getSelection(); // true = IN . false = OUT
					// If new state is IN - Set to IN
					if(btnState){
						// Set btn-text to IN
						btn.setText("IN");
						// Set pin-mode of the Arduino pin to Input
						myMediator.arduinoFirmata.pinMode(pin, 0);  // 0: INPUT, 1:OUTPUT
						// Save to prefs
						myMediator.prefs.put("pinmode"+pin, "IN");
					} else {
					// If current state is OUT - Set to OUT
						// Set btn-text to OUT
						btn.setText("OUT");
						// Set pin-mode of the Arduino pin to output						
						myMediator.arduinoFirmata.pinMode(pin, 1);  // 0: INPUT, 1:OUTPUT
						// Save to prefs
						myMediator.prefs.put("pinmode"+pin, "OUT");
					}
					// Save the new state of the button to pref
				}
			});

		}

	}
	
	protected void fillArduinoValues(){
		// We do not run this, if there is no arduino boar
		
		if(myMediator.arduinoFirmata != null){
		
			// loop through the children of composite_analogValues and set the text to the value
			for(int i = 0;i<6;i++){
				int pinval = myMediator.arduinoFirmata.analogRead(i);
				Label lbl = (Label)getComposite_analogValues().getChildren()[i];
				lbl.setText(""+pinval);
			}
			// loop through the children of analog composite_digitalValues and set the text to the value
			// Start from 2 since 0 and 1 are rx tx
			for(int i = 2;i<14;i++){
				int pinval = myMediator.arduinoFirmata.digitalRead(i);
				Label lbl = (Label)getComposite_digitalValues().getChildren()[i];
				lbl.setText(""+pinval);
			}
		}
	}
	protected Composite getComposite_analogValues() {
		return composite_analogValues;
	}
	protected Composite getComposite_digitalValues() {
		return composite_digitalValues;
	}
}
